home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d928.lha / PriMan / PriMan.c < prev    next >
C/C++ Source or Header  |  1993-10-07  |  51KB  |  1,077 lines

  1. /*
  2.  
  3.     Task Priority Manager
  4.     Copyright 1993 Barry McConnell
  5.     bmccnnll@unix1.tcd.ie
  6.  
  7. */
  8.  
  9. #include <exec/types.h>
  10. #include <exec/memory.h>
  11. #include <exec/execbase.h>
  12. #include <dos/dos.h>
  13. #include <dos/dosextens.h>
  14. #include <intuition/intuition.h>
  15. #include <intuition/gadgetclass.h>
  16. #include <intuition/screens.h>
  17. #include <graphics/text.h> 
  18. #include <graphics/gfxbase.h>
  19. #include <libraries/gadtools.h>
  20. #include <libraries/asl.h>
  21. #include <workbench/startup.h>
  22. #include <workbench/workbench.h>
  23.  
  24. #include <proto/dos.h>
  25. #include <proto/exec.h>
  26. #include <proto/intuition.h>
  27. #include <proto/graphics.h>
  28. #include <proto/gadtools.h>
  29. #include <proto/diskfont.h>
  30. #include <proto/asl.h>
  31. #include <proto/icon.h>
  32.  
  33. #include <stdio.h>
  34. #include <string.h>
  35.  
  36. #define WINDOWIDCMP     IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE | BUTTONIDCMP | LISTVIEWIDCMP | RAWKEY
  37. #define DefFontLength   15  /* including the size */
  38. #define MaxFontLength   30  /* well, have YOU seen any font names longer than this?? */
  39. #define ScrollBarWidth  16
  40.  
  41. #define LISTGAD         1
  42. #define SLIDERGAD       2
  43. #define BREAKGAD        3
  44. #define KILLGAD         4
  45. #define SETTINGSGAD     5
  46. #define GFONTGAD        6
  47. #define LFONTGAD        7
  48. #define GBOXGAD         8
  49. #define LBOXGAD         9
  50. #define CHECKGAD        10
  51. #define SAVEGAD         11
  52. #define USEGAD          12
  53. #define CANCELGAD       13
  54.  
  55. void __regargs __chkabort(void) {}  /* turn off SAS/C v6 CTRL-C checking */
  56.  
  57. int showTasks(void);
  58. int handleSettings(struct Screen *, struct Window *,
  59.                     struct Gadget *, struct Gadget *, struct Gadget *, struct Gadget *,
  60.                     WORD, WORD, WORD);
  61.  
  62. struct listType  /* standard Node type with extra space to store the original task structure, so we can find it again */
  63.     {
  64.     struct Node mainNode;
  65.     struct Task *mainTask;
  66.     };
  67.  
  68. struct FontRequester    *propFontReq = NULL, *monoFontReq = NULL;
  69. struct TextAttr         propName = { "                         ", 0, 0, 0 },
  70.                         monoName = { "                         ", 0, 0, 0 };
  71.  
  72. extern struct ExecBase *SysBase;
  73. static UBYTE *version = "$VER: PriMan 1.0 (03.09.93)";
  74. char *myName = NULL;  /* to be filled in from WBStartup message */
  75. int workbench = 0;  /* started from CLI or Workbench? */
  76. UWORD osver = 0;  /* Kickstart version */
  77. WORD winLeft = 150, winTop = 50, winWidth = 220, winHeight = 270, confirm = 1;  /* default settings */
  78.  
  79. UWORD __chip waitPointer[] =
  80.     {
  81.     0x0000, 0x0000,
  82.     0x0400, 0x07c0,
  83.     0x0000, 0x07c0,
  84.     0x0100, 0x0380,
  85.     0x0000, 0x07e0,
  86.     0x07c0, 0x1ff8,
  87.     0x1ff0, 0x3fec,
  88.     0x3ff8, 0x7fde,
  89.     0x3ff8, 0x7fbe,
  90.     0x7ffc, 0xff7f,
  91.     0x7efc, 0xffff,
  92.     0x7ffc, 0xffff,
  93.     0x3ff8, 0x7ffe,
  94.     0x3ff8, 0x7ffe,
  95.     0x1ff0, 0x3ffc,
  96.     0x07c0, 0x1ff8,
  97.     0x0000, 0x07e0,
  98.     0x0000, 0x0000,
  99.     };
  100.  
  101.  
  102. /*
  103.     Display a busy pointer in the current window, and prevent user from
  104.     clicking on any gadgets. The immediate flag prevents the short delay
  105.     (under 3.x) before the pointer changes.
  106. */
  107.  
  108. void busyPointer(struct Window *myWindow, struct Requester *myReq, BOOL immediate)
  109. {
  110. InitRequester(myReq);
  111. Request(myReq, myWindow);
  112. if (osver < 39 || immediate)
  113.     SetPointer(myWindow, waitPointer, 16, 16, -6, 0);
  114. else
  115.     SetWindowPointer(myWindow,  WA_BusyPointer,     TRUE,
  116.                                 WA_PointerDelay,    TRUE,
  117.                                 TAG_END);
  118. }
  119.  
  120.  
  121. /*
  122.     Restore the pointer to normal. The keepPointer flag just removes the invisible
  123.     requester without restoring the normal pointer image.
  124. */
  125.  
  126. void normalPointer(struct Window *myWindow, struct Requester *myReq, BOOL keepPointer)
  127. {
  128. if (!keepPointer)
  129.     ClearPointer(myWindow);
  130. EndRequest(myReq, myWindow);
  131. }
  132.  
  133.  
  134. /*
  135.     Join a text string (task or font name) and a number (priority or size) together.
  136.  
  137.     If it's a task, extra spaces are placed between the two components to make the
  138.     string an exact length. If the task has an appropriate CLI number, that will be
  139.     added in before the task name.
  140.  
  141.     If it's a font, the routine stops at a dot (i.e. in "x.font"), and places a
  142.     single space between it and the size.
  143.  
  144.     There must be length+1 bytes free in dest, because of the \0 char.
  145. */
  146.  
  147. void createString(struct Task *task, struct TextAttr *font, char *dest, int length)
  148. {
  149. int numLen, cli, i = 0, j = 0;
  150. char digits[5], clitext[11];
  151. char *name;
  152. APTR bstr;
  153. BYTE maxlen = -1;
  154.  
  155. if (task)  /* dealing with a task or a font? */
  156.     {
  157.     numLen = sprintf(digits, "%d", task -> tc_Node.ln_Pri);  /* saves me writing an integer -> ASCII routine */
  158.  
  159.     if (((task -> tc_Node.ln_Type) == NT_PROCESS) && (cli = ((struct Process *)task) -> pr_TaskNum))  /* is it a process with a CLI attached? */
  160.         {
  161.         sprintf(clitext, "CLI #%d: ", cli);
  162.         for (; (i < length - numLen - 1) && clitext[i]; i++)
  163.             dest[i] = clitext[i];
  164.         bstr = BADDR(((struct CommandLineInterface *)(BADDR(((struct Process *)task) -> pr_CLI))) -> cli_CommandName);
  165.         name = (char *)(bstr)+1;
  166.         maxlen = *((BYTE *)bstr);
  167.         }
  168.     else
  169.         name = task -> tc_Node.ln_Name;
  170.     }
  171.  
  172. else  /* font */
  173.     {
  174.     numLen = sprintf(digits, "%d", font -> ta_YSize);
  175.     name = font -> ta_Name;
  176.     }
  177.  
  178. for (; (i < length - numLen - 1) && name[j] && maxlen && !((name[j] == '.') && font); i++, j++, maxlen--)
  179.     dest[i] = name[j];
  180.  
  181. do
  182.     dest[i++] = ' ';
  183. while ((i < length - numLen) && task);  /* only insert one space if it's a font name */
  184.  
  185. j = 0;
  186. do
  187.     dest[i++] = digits[j];
  188. while (digits[j++]);
  189. }
  190.  
  191.  
  192. /*
  193.     Compare two strings. Like "strcmp" but case-insensitive.
  194. */
  195.  
  196. int Compare(char *s, char *t)
  197. {
  198. for (; ((*s & ~32) == (*t & ~32)) && *s; s++, t++)  /* sorry, K&R ;-) */
  199.     ;
  200. return (*s & ~32) - (*t & ~32);
  201. }
  202.  
  203.  
  204. /*
  205.     Alphabetically insert "node" into "list".
  206. */
  207.  
  208. void Sort(struct List *list, struct Node *node)
  209. {
  210. struct Node *temp = list -> lh_Head;
  211.  
  212. while ((temp -> ln_Succ) && Compare(temp -> ln_Name, node -> ln_Name) < 0)
  213.     temp = temp -> ln_Succ;
  214.  
  215. Insert(list, node, temp -> ln_Pred);
  216. }
  217.  
  218.  
  219. /*
  220.     Add an Exec task list ("source") onto our own one ("dest").
  221.     Allocates memory as necessary, and preserves alphabetical order.
  222.     If we just want to add one task, use the last parameter ("single") -
  223.     in this case, "source" will be ignored.
  224. */
  225.  
  226. int BuildList(struct List *source, struct List *dest, struct Remember **memoryKey, int taskLength, struct Task *single)
  227. {
  228. struct Node     *execNode;
  229. struct listType *taskNode;
  230. int             success = TRUE;
  231. UBYTE           *taskString;
  232.  
  233. if (single)
  234.     {
  235.     if ((taskNode = AllocRemember(memoryKey, sizeof(struct listType), MEMF_ANY))
  236.         && (taskString = AllocRemember(memoryKey, taskLength + 1, MEMF_ANY)))
  237.         {
  238.         createString(single, NULL, taskString, taskLength);
  239.         taskNode -> mainNode.ln_Name = taskString;
  240.         taskNode -> mainNode.ln_Pri = single -> tc_Node.ln_Pri;
  241.         taskNode -> mainTask = single;
  242.         Sort(dest, (struct Node *)taskNode);
  243.         }
  244.     else
  245.         success = FALSE;
  246.     }
  247. else
  248.     {   
  249.     for (execNode = source -> lh_Head; (execNode -> ln_Succ) && success; execNode = execNode -> ln_Succ)
  250.         {
  251.         if ((taskNode = AllocRemember(memoryKey, sizeof(struct listType), MEMF_ANY))
  252.             && (taskString = AllocRemember(memoryKey, taskLength + 1, MEMF_ANY)))
  253.             {
  254.             createString((struct Task *)execNode, NULL, taskString, taskLength);
  255.             taskNode -> mainNode.ln_Name = taskString;
  256.             taskNode -> mainNode.ln_Pri = execNode -> ln_Pri;
  257.             taskNode -> mainTask = (struct Task *)execNode;
  258.             Sort(dest, (struct Node *)taskNode);
  259.             }
  260.         else
  261.             success = FALSE;
  262.         }
  263.     }
  264. return success;
  265. }
  266.  
  267.  
  268. /*
  269.     Search for given ToolType in array.
  270.     Fills in string -> decimal value if found.
  271. */
  272.  
  273. void match(char *tool, char **array, WORD *value)
  274. {
  275. char    *string;
  276. int     temp;
  277.  
  278. if (string = FindToolType(array, tool))  /* is it there? */
  279.     {
  280.     sscanf(string, "%d", &temp);  /* read it into type "int" */
  281.     *value = temp;  /* convert to "word" */
  282.     }
  283. }
  284.  
  285.  
  286. void main(int argc, char *argv[])
  287. {
  288. struct DiskObject   *myIcon;
  289. char                **tools, *string;
  290.  
  291. if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37))
  292.     {
  293.     if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37))
  294.         {
  295.         if (GadToolsBase = OpenLibrary("gadtools.library", 37))
  296.             {
  297.             if (IconBase = OpenLibrary("icon.library", 37))
  298.                 {
  299.                 osver = SysBase -> LibNode.lib_Version;  /* running under 2.0, 3.0, ...? */
  300.  
  301.                 if (workbench = !argc)  /* only look at ToolTypes if started from Workbench */
  302.                     {
  303.                     myName = ((struct WBStartup *)argv) -> sm_ArgList -> wa_Name;  /* find ourselves */
  304.                     if (myIcon = GetDiskObject(myName));  /* read in .info file */
  305.                         {
  306.                         tools = myIcon -> do_ToolTypes;
  307.  
  308.                         match("LEFT", tools, &winLeft);  /* start searching for valid ToolTypes */
  309.                         match("TOP", tools, &winTop);
  310.                         match("WIDTH", tools, &winWidth);
  311.                         match("HEIGHT", tools, &winHeight);
  312.                         match("GADSIZE", tools, &(propName.ta_YSize));
  313.                         match("LISTSIZE", tools, &(monoName.ta_YSize));
  314.  
  315.                         if (string = FindToolType(tools, "GADFONT"))
  316.                             sscanf(string, "%s", propName.ta_Name);
  317.                         if (string = FindToolType(tools, "LISTFONT"))
  318.                             sscanf(string, "%s", monoName.ta_Name);
  319.                         if (string = FindToolType(tools, "CONFIRM"))
  320.                             confirm = !(string[0] == 'N' && string[1] == 'O');  /* user must be exact! */
  321.  
  322.                         FreeDiskObject(myIcon);
  323.                         }
  324.                     }
  325.  
  326.                 propFontReq = AllocAslRequest(ASL_FontRequest, NULL);
  327.                 monoFontReq = AllocAslRequest(ASL_FontRequest, NULL);
  328.  
  329.                 while (showTasks())
  330.                     ;
  331.  
  332.                 FreeAslRequest(propFontReq);
  333.                 FreeAslRequest(monoFontReq);
  334.  
  335.                 CloseLibrary(IconBase);
  336.                 }
  337.             CloseLibrary(GadToolsBase);
  338.             }
  339.         CloseLibrary((struct Library *)GfxBase);
  340.         }
  341.     CloseLibrary((struct Library *)IntuitionBase);
  342.     }
  343. }
  344.  
  345.  
  346. int showTasks(void)
  347. {
  348. static struct Window    *myWindow;  /* allow resizing without closing it */
  349. static int              windowValid = FALSE;
  350.  
  351. struct Screen       *myScreen;
  352. struct TextFont     *propFont, *monoFont;
  353. struct TextExtent   fontSize = { NULL, NULL };
  354. struct RastPort     myRast;
  355. struct Image        blank = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  356. struct IntuiMessage *message;
  357. struct Task         *currentTask;
  358. struct List         taskList;
  359. struct Remember     *memoryKey;
  360. struct Requester    tinyReq;
  361. struct Node         *current;
  362. struct NewGadget    myGad;
  363. struct Gadget       *mainGads, *setGads, *prevGad, *prevGad2, *selectedGad,
  364.                     *listGad, *sliderGad, *breakGad, *killGad, *propFontGad, *monoFontGad, *checkGad;
  365.  
  366. void    *visInfo;
  367. WORD    height, width, sysHeight, sysWidth, windowTop, listWidth, buttonWidth, minWidth, minHeight,
  368.         setWidth, setHeight, buttonText, fontText, confirmText, cancelText, code;
  369. ULONG   class;
  370. int     taskLength, exit = 0, redraw = 0, preserve = 0, update = 0, wide = 0, pos, button;
  371.  
  372. struct EasyStruct about =  /* And the user thought he was getting full online help... */
  373.     {
  374.     sizeof(struct EasyStruct),
  375.     0,
  376.     "About PriMan",
  377.     "Task Priority Manager v1.0\nFreely Distributable\nCopyright 1993 Barry McConnell\nbmccnnll@unix1.tcd.ie",
  378.     "Okay"
  379.     };
  380.  
  381. struct EasyStruct lost =  /* Oi! Where did that task go? */
  382.     {
  383.     sizeof(struct EasyStruct),
  384.     0,
  385.     "PriMan trouble",
  386.     "Task was not found!",
  387.     "Okay"
  388.     };
  389.  
  390. struct EasyStruct signal =
  391.     {
  392.     sizeof(struct EasyStruct),
  393.     0,
  394.     "PriMan warning",
  395.     "Really signal `%s'\nwith Ctrl-C?",
  396.     "Signal|Cancel"
  397.     };
  398.  
  399. struct EasyStruct kill =
  400.     {
  401.     sizeof(struct EasyStruct),
  402.     0,
  403.     "PriMan warning",
  404.     "Really remove `%s'?",
  405.     "Remove|Cancel"
  406.     };
  407.  
  408. if (myScreen = LockPubScreen(NULL))
  409.     {
  410.     if (visInfo = GetVisualInfo(myScreen, TAG_END))
  411.         {
  412.         if (!propName.ta_YSize || propName.ta_Name[0] == ' ')  /* invalid font structure */
  413.             {
  414.             propName.ta_YSize = myScreen -> Font -> ta_YSize;
  415.             strcpy(propName.ta_Name, myScreen -> Font -> ta_Name);
  416.             }
  417.  
  418.         if (!monoName.ta_YSize || monoName.ta_Name[0] == ' ')
  419.             {
  420.             monoName.ta_YSize = GfxBase -> DefaultFont -> tf_YSize;
  421.             strcpy(monoName.ta_Name, GfxBase -> DefaultFont -> tf_Message.mn_Node.ln_Name);
  422.             }
  423.  
  424.         if ((propFont = OpenDiskFont(&propName)) && (monoFont = OpenDiskFont(&monoName)))
  425.             {
  426.             FontExtent(propFont, &fontSize);  /* figure out pixel size of fonts */
  427.             height = fontSize.te_Height;
  428.             width = fontSize.te_Width;
  429.             FontExtent(monoFont, &fontSize);
  430.             sysHeight = fontSize.te_Height;
  431.             sysWidth = fontSize.te_Width;
  432.  
  433.             InitRastPort(&myRast);  /* dummy RastPort for getting string lengths */
  434.             myRast.Font = propFont;
  435.  
  436.             buttonText  = TextLength(&myRast, "Settings...", 11) + INTERWIDTH * 2;
  437.             fontText    = TextLength(&myRast, "Gadget Font...", 14) + INTERWIDTH * 2;
  438.             confirmText = TextLength(&myRast, "Confirm actions?", 16);
  439.             cancelText  = TextLength(&myRast, "Cancel", 6) + INTERWIDTH * 2;
  440.  
  441.             windowTop   = (myScreen -> WBorTop) + myScreen -> Font -> ta_YSize + 1 + INTERHEIGHT;
  442.             listWidth   = sysWidth * 7 + ScrollBarWidth + INTERWIDTH * 3 + (osver < 39 ? 4 : 0);  /* full width of a small window (a bug in 2.x clips 4 pixels too early) */
  443.             buttonWidth = buttonText * 3 + INTERWIDTH * 4;  /* width of buttons and spacing */
  444.             minWidth    = buttonWidth > listWidth ? buttonWidth : listWidth;  /* choose between them */
  445.             minHeight   = windowTop + sysHeight * (osver < 39 ? 5 : 3) + height + INTERHEIGHT * 8 + 2;  /* small ListView (1 or 2 elements) */
  446.  
  447.             if (winWidth < minWidth)  /* so, which is it to be? */
  448.                 winWidth = minWidth;
  449.             if (winWidth > myScreen -> Width)
  450.                 winWidth = myScreen -> Width;
  451.             if (winHeight < minHeight)
  452.                 winHeight = minHeight;
  453.             if (winHeight > myScreen -> Height)
  454.                 winHeight = myScreen -> Height;
  455.  
  456.             taskLength  = (winWidth - ScrollBarWidth - INTERWIDTH * 3 - (osver < 39 ? 4 : 0)) / sysWidth;
  457.  
  458.             mainGads    = NULL;  /* begin laying out gadgets for main window */
  459.             prevGad     = CreateContext(&mainGads);
  460.  
  461.             myGad.ng_LeftEdge   = INTERWIDTH;
  462.             myGad.ng_TopEdge    = windowTop;
  463.             myGad.ng_Width      = winWidth - INTERWIDTH * 2;
  464.             myGad.ng_Height     = winHeight - windowTop - sysHeight - height - INTERHEIGHT * 7 - 2;
  465.             myGad.ng_GadgetText = NULL;
  466.             myGad.ng_TextAttr   = &monoName;
  467.             myGad.ng_GadgetID   = LISTGAD;
  468.             myGad.ng_Flags      = NULL;
  469.             myGad.ng_VisualInfo = visInfo;
  470.  
  471.             prevGad = listGad = CreateGadget(LISTVIEW_KIND, prevGad, &myGad,
  472.                                                 GTLV_Labels,            NULL,
  473.                                                 GTLV_ShowSelected,      NULL,
  474.                                                 TAG_END);
  475.  
  476.             if (!(windowValid || osver < 39))  /* if possible, silently adjust its height for perfect spacing */
  477.                 {
  478.                 winHeight += listGad -> Height - myGad.ng_Height;  /* A bug in 2.x doesn't give the correct value */
  479.                 myGad.ng_Height = listGad -> Height;  /* ListView may have ended up smaller */
  480.                 }
  481.  
  482.             myGad.ng_LeftEdge   += sysWidth * 4 + INTERWIDTH;
  483.             myGad.ng_TopEdge    += myGad.ng_Height + INTERHEIGHT;
  484.             myGad.ng_Width      = winWidth - INTERWIDTH - myGad.ng_LeftEdge;
  485.             myGad.ng_Height     = sysHeight + INTERHEIGHT;
  486.             myGad.ng_GadgetID   = SLIDERGAD;
  487.  
  488.             prevGad = sliderGad = CreateGadget(SLIDER_KIND, prevGad, &myGad,
  489.                                                 GTSL_Min,           -25,
  490.                                                 GTSL_Max,           25,
  491.                                                 GTSL_Level,         0,
  492.                                                 GTSL_LevelFormat,   "%4ld",
  493.                                                 GTSL_MaxLevelLen,   4,
  494.                                                 GTSL_LevelPlace,    PLACETEXT_LEFT,
  495.                                                 GA_RelVerify,       TRUE,
  496.                                                 GA_Disabled,        TRUE,
  497.                                                 TAG_END);
  498.  
  499.             myGad.ng_LeftEdge   = INTERWIDTH;
  500.             myGad.ng_TopEdge    += myGad.ng_Height + INTERHEIGHT;
  501.             myGad.ng_Width      = buttonText;
  502.             myGad.ng_Height     = height + INTERHEIGHT;
  503.             myGad.ng_GadgetText = "Break";
  504.             myGad.ng_TextAttr   = &propName;
  505.             myGad.ng_GadgetID   = BREAKGAD;
  506.  
  507.             prevGad = breakGad = CreateGadget(BUTTON_KIND, prevGad, &myGad,
  508.                                                 GA_Disabled, TRUE,
  509.                                                 TAG_END);
  510.  
  511.             myGad.ng_LeftEdge   += buttonText + (winWidth - INTERWIDTH *2 - buttonText * 3) / 2;
  512.             myGad.ng_GadgetText = "Kill";
  513.             myGad.ng_GadgetID   = KILLGAD;
  514.  
  515.             prevGad = killGad = CreateGadget(BUTTON_KIND, prevGad, &myGad,
  516.                                                 GA_Disabled, TRUE,
  517.                                                 TAG_END);
  518.  
  519.             myGad.ng_LeftEdge   += buttonText + (winWidth - INTERWIDTH *2 - buttonText * 3) / 2;
  520.             myGad.ng_GadgetText = "Settings...";
  521.             myGad.ng_GadgetID   = SETTINGSGAD;
  522.  
  523.             prevGad = CreateGadget(BUTTON_KIND, prevGad, &myGad, TAG_END);
  524.  
  525.             setGads = NULL;  /* now the settings window */
  526.             prevGad2 = CreateContext(&setGads);
  527.  
  528.             myGad.ng_LeftEdge   = INTERWIDTH;
  529.             myGad.ng_TopEdge    = windowTop;
  530.             myGad.ng_Width      = fontText;
  531.             myGad.ng_GadgetText = "Gadget Font...";
  532.             myGad.ng_GadgetID   = GFONTGAD;
  533.  
  534.             prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad, TAG_END);
  535.  
  536.             myGad.ng_LeftEdge   += confirmText + INTERWIDTH;
  537.             myGad.ng_Width      = width * DefFontLength + INTERWIDTH;
  538.             myGad.ng_GadgetText = NULL;
  539.             myGad.ng_GadgetID   = GBOXGAD;
  540.  
  541.             prevGad2 = propFontGad = CreateGadget(TEXT_KIND, prevGad2, &myGad,
  542.                                                     GTTX_Border,    TRUE,
  543.                                                     TAG_END);
  544.  
  545.             setWidth = myGad.ng_LeftEdge + myGad.ng_Width + INTERWIDTH;
  546.  
  547.             myGad.ng_LeftEdge   = INTERWIDTH;
  548.             myGad.ng_TopEdge    += myGad.ng_Height + INTERHEIGHT;
  549.             myGad.ng_Width      = fontText;
  550.             myGad.ng_GadgetText = "List Font...";
  551.             myGad.ng_GadgetID   = LFONTGAD;
  552.  
  553.             prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad, TAG_END);
  554.  
  555.             myGad.ng_LeftEdge   += confirmText + INTERWIDTH;
  556.             myGad.ng_Width      = width * DefFontLength + INTERWIDTH;
  557.             myGad.ng_GadgetText = NULL;
  558.             myGad.ng_GadgetID   = LBOXGAD;
  559.  
  560.             prevGad2 = monoFontGad = CreateGadget(TEXT_KIND, prevGad2, &myGad,
  561.                                                     GTTX_Border,    TRUE,
  562.                                                     TAG_END);
  563.  
  564.             myGad.ng_LeftEdge   = INTERWIDTH;
  565.             myGad.ng_TopEdge    += myGad.ng_Height + INTERHEIGHT;
  566.             myGad.ng_Width      = confirmText;
  567.             myGad.ng_Height     = height + INTERHEIGHT;
  568.             myGad.ng_TextAttr   = &propName;
  569.             myGad.ng_GadgetID   = NULL;
  570.  
  571.             prevGad2 = CreateGadget(TEXT_KIND, prevGad2, &myGad,
  572.                                     GTTX_Text,  "Confirm actions?",
  573.                                     TAG_END);
  574.  
  575.             myGad.ng_LeftEdge   += myGad.ng_Width  + INTERWIDTH;
  576.             myGad.ng_TopEdge    += (height + INTERHEIGHT - 11) / 2;
  577.             myGad.ng_GadgetID   = CHECKGAD;
  578.  
  579.             prevGad2 = checkGad = CreateGadget(CHECKBOX_KIND, prevGad2, &myGad, TAG_END);
  580.  
  581.             myGad.ng_LeftEdge   = INTERWIDTH;
  582.             myGad.ng_TopEdge    += height + INTERHEIGHT * 2 - (height + INTERHEIGHT - 11) / 2;
  583.             myGad.ng_Width      = cancelText;
  584.             myGad.ng_GadgetText = "Save";
  585.             myGad.ng_GadgetID   = SAVEGAD;
  586.  
  587.             prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad,
  588.                                     GA_Disabled,    !workbench,  /* CLI users can't open the .info file */
  589.                                     TAG_END);
  590.  
  591.             myGad.ng_LeftEdge   += cancelText + (setWidth - INTERWIDTH *2 - cancelText * 3) / 2;
  592.             myGad.ng_GadgetText = "Use";
  593.             myGad.ng_GadgetID   = USEGAD;
  594.  
  595.             prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad, TAG_END);
  596.  
  597.             myGad.ng_LeftEdge   += cancelText + (setWidth - INTERWIDTH *2 - cancelText * 3) / 2;
  598.             myGad.ng_GadgetText = "Cancel";
  599.             myGad.ng_GadgetID   = CANCELGAD;
  600.  
  601.             prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad, TAG_END);
  602.  
  603.             setHeight = myGad.ng_TopEdge + myGad.ng_Height + INTERHEIGHT + 2;
  604.  
  605.             if (prevGad && prevGad2)
  606.                 {
  607.                 if (windowValid)  /* it may already be open and just needs updating */
  608.                     {
  609.                     AddGList(myWindow, mainGads, ~0, -1, NULL);
  610.                     RefreshGList(mainGads, myWindow, NULL, -1);
  611.                     windowValid = FALSE;
  612.                     }
  613.                 else
  614.                     myWindow = OpenWindowTags(NULL, WA_Title,       "Task Priority Manager",
  615.                                                     WA_Gadgets,     mainGads,
  616.                                                     WA_Left,        winLeft,
  617.                                                     WA_Top,         winTop,
  618.                                                     WA_Width,       winWidth,
  619.                                                     WA_Height,      winHeight,
  620.                                                     WA_MinWidth,    minWidth,
  621.                                                     WA_MinHeight,   minHeight,
  622.                                                     WA_MaxWidth,    ~0,
  623.                                                     WA_MaxHeight,   ~0,
  624.                                                     WA_DragBar,     TRUE,
  625.                                                     WA_DepthGadget, TRUE,
  626.                                                     WA_CloseGadget, TRUE,
  627.                                                     WA_SizeGadget,  TRUE,
  628.                                                     WA_SizeBBottom, TRUE,
  629.                                                     WA_Activate,    TRUE,
  630.                                                     WA_RMBTrap,     TRUE,
  631.                                                     WA_IDCMP,       WINDOWIDCMP,
  632.                                                     WA_PubScreen,   myScreen,
  633.                                                     TAG_END);
  634.  
  635.                 if (myWindow)  /* either just opened, or else we added the gadget list above */
  636.                     {
  637.                     GT_RefreshWindow(myWindow, NULL);
  638.  
  639.                     do
  640.                         {
  641.                         if (update)  /* may need to remove obsolete task list first */
  642.                             {
  643.                             GT_SetGadgetAttrs(listGad, myWindow, NULL,
  644.                                                 GTLV_Labels,    ~0,
  645.                                                 TAG_END);
  646.                             FreeRemember(&memoryKey, TRUE);
  647.                             exit = update = 0;
  648.                             }
  649.  
  650.                         memoryKey = NULL;
  651.  
  652.                         taskList.lh_Head        = (struct Node *) &taskList.lh_Tail;
  653.                         taskList.lh_Tail        = NULL;
  654.                         taskList.lh_TailPred    = (struct Node *) &taskList.lh_Head;
  655.  
  656.                         Disable();  /* going to walk Exec's task list */
  657.  
  658.                         if (BuildList(&(SysBase -> TaskReady), &taskList, &memoryKey, taskLength, NULL)
  659.                             && BuildList(&(SysBase -> TaskWait), &taskList, &memoryKey, taskLength, NULL)
  660.                             && BuildList(NULL, &taskList, &memoryKey, taskLength, FindTask(NULL)))
  661.                             {
  662.                             Enable();
  663.                             GT_SetGadgetAttrs(listGad, myWindow, NULL,
  664.                                                 GTLV_Labels,    &taskList,
  665.                                                 GTLV_Selected,  ~0,
  666.                                                 TAG_END);
  667.                             GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
  668.                                                 GA_Disabled,    TRUE,
  669.                                                 TAG_END);
  670.                             GT_SetGadgetAttrs(breakGad, myWindow, NULL,
  671.                                                 GA_Disabled,    TRUE,
  672.                                                 TAG_END);
  673.                             GT_SetGadgetAttrs(killGad, myWindow, NULL,
  674.                                                 GA_Disabled,    TRUE,
  675.                                                 TAG_END);
  676.                             pos = -1;  /* ignore any "leftover" requests to break / kill */
  677.  
  678.                             do
  679.                                 {
  680.                                 WaitPort(myWindow -> UserPort);
  681.                                 if (message = GT_GetIMsg(myWindow -> UserPort))  /* GadTools filters out most of them */
  682.                                     {
  683.                                     if ((class = message -> Class) == GADGETUP)
  684.                                         selectedGad = message -> IAddress;
  685.                                     code = message -> Code;
  686.                                     GT_ReplyIMsg(message);
  687.  
  688.                                     switch (class)
  689.                                         {
  690.                                         case IDCMP_CLOSEWINDOW:
  691.                                             exit = 1;
  692.                                             break;
  693.  
  694.                                         case IDCMP_NEWSIZE:
  695.                                             exit = redraw = preserve = 1;
  696.                                             break;
  697.  
  698.                                         case IDCMP_REFRESHWINDOW:
  699.                                             GT_BeginRefresh(myWindow);
  700.                                             GT_EndRefresh(myWindow, TRUE);
  701.                                             break;
  702.  
  703.                                         case GADGETUP:
  704.                                             switch (selectedGad -> GadgetID)
  705.                                                 {
  706.                                                 case LISTGAD:
  707.                                                     pos = code;
  708.                                                     for (current = taskList.lh_Head; code > 0; current = current -> ln_Succ, code --)  /* find selected task */
  709.                                                         ;
  710.  
  711.                                                     if (wide = (current -> ln_Pri < -25 || current -> ln_Pri > 25))  /* wide or narrow scale? */
  712.                                                         GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
  713.                                                                             GTSL_Min,   -128,
  714.                                                                             GTSL_Max,   127,
  715.                                                                             TAG_END);
  716.                                                     else
  717.                                                         GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
  718.                                                                             GTSL_Min,   -25,
  719.                                                                             GTSL_Max,   25,
  720.                                                                             TAG_END);
  721.  
  722.                                                     GT_SetGadgetAttrs(sliderGad, myWindow, NULL,  /* update slider gadget to new task's priority */
  723.                                                                         GTSL_Level,     current -> ln_Pri,
  724.                                                                         GA_Disabled,    FALSE,
  725.                                                                         TAG_END);
  726.                                                     GT_SetGadgetAttrs(breakGad, myWindow, NULL,
  727.                                                                         GA_Disabled,    FALSE,
  728.                                                                         TAG_END);
  729.                                                     GT_SetGadgetAttrs(killGad, myWindow, NULL,
  730.                                                                         GA_Disabled,    FALSE,
  731.                                                                         TAG_END);
  732.                                                     break;
  733.  
  734.                                                 case SLIDERGAD:
  735.                                                     currentTask = ((struct listType *)current) -> mainTask;
  736.                                                     if (currentTask -> tc_State < 2 || currentTask -> tc_State > 4)  /* not a valid task */
  737.                                                         {
  738.                                                         busyPointer(myWindow, &tinyReq, FALSE);
  739.                                                         EasyRequest(NULL, &lost, NULL, NULL);
  740.                                                         normalPointer(myWindow, &tinyReq, FALSE);
  741.                                                         exit = update = 1;
  742.                                                         }
  743.                                                     else
  744.                                                         {
  745.                                                         SetTaskPri(currentTask, (WORD)code);
  746.                                                         GT_SetGadgetAttrs(listGad, myWindow, NULL,
  747.                                                                             GTLV_Labels,    ~0,
  748.                                                                             TAG_END);
  749.                                                         createString(currentTask, FALSE, current -> ln_Name, taskLength);
  750.                                                         current -> ln_Pri = (WORD)code;
  751.                                                         GT_SetGadgetAttrs(listGad, myWindow, NULL,
  752.                                                                             GTLV_Labels,    &taskList,
  753.                                                                             GTLV_Selected,  pos,  /* only required under 2.0 */
  754.                                                                             TAG_END);
  755.                                                         }
  756.                                                     break;
  757.  
  758.                                                 case BREAKGAD:
  759.                                                 case KILLGAD:
  760.                                                     if (!(pos == -1))
  761.                                                         {
  762.                                                         busyPointer(myWindow, &tinyReq, FALSE);
  763.                                                         currentTask = ((struct listType *)current) -> mainTask;
  764.                                                         if (currentTask -> tc_State < 2 || currentTask -> tc_State > 4)
  765.                                                             {
  766.                                                             EasyRequest(NULL, &lost, NULL, NULL);
  767.                                                             exit = update = 1;
  768.                                                             }
  769.                                                         else
  770.                                                             {
  771.                                                             if (confirm)
  772.                                                                 button = EasyRequest(NULL, (selectedGad -> GadgetID == BREAKGAD) ? &signal : &kill, NULL, currentTask -> tc_Node.ln_Name);
  773.                                                             if (button || !confirm)  /* user clicked "Okay" */
  774.                                                                 {
  775.                                                                 Disable();
  776.                                                                 if (currentTask -> tc_State >= 2 && currentTask -> tc_State <= 4)  /* paranoid! */
  777.                                                                     {
  778.                                                                     if (selectedGad -> GadgetID == BREAKGAD)
  779.                                                                         {
  780.                                                                         Signal(currentTask, SIGBREAKF_CTRL_C);
  781.                                                                         Enable();
  782.                                                                         Delay(25);  /* allow time for task to exit */
  783.                                                                         }
  784.                                                                     else
  785.                                                                         {
  786.                                                                         RemTask(currentTask);  /* BLAM! */
  787.                                                                         Enable();
  788.                                                                         }
  789.                                                                     }
  790.                                                                 exit = update = 1;
  791.                                                                 }
  792.                                                             }
  793.                                                         normalPointer(myWindow, &tinyReq, FALSE);
  794.                                                         }
  795.                                                     break;
  796.  
  797.                                                 case SETTINGSGAD:
  798.                                                     WindowLimits(myWindow, winWidth, winHeight, winWidth, winHeight);
  799.                                                     busyPointer(myWindow, &tinyReq, FALSE);
  800.                                                     if (handleSettings(myScreen, myWindow, setGads, propFontGad, monoFontGad, checkGad, setWidth, setHeight, windowTop))
  801.                                                             exit = redraw = 1;
  802.                                                     normalPointer(myWindow, &tinyReq, FALSE);
  803.                                                     WindowLimits(myWindow, minWidth, minHeight, ~0, ~0);
  804.                                                     break;
  805.                                                 }
  806.                                             break;
  807.  
  808.                                         case RAWKEY:
  809.                                             switch (code)
  810.                                                 {
  811.                                                 case 64:
  812.                                                 case 68:  /* Space or Return keys */
  813.                                                     exit = update = 1;
  814.                                                     break;
  815.  
  816.                                                 case 66:  /* Tab key */
  817.                                                     if (!(pos == -1))  /* don't change the scale of a disabled slider */
  818.                                                         {
  819.                                                         if (current -> ln_Pri > -26 && current -> ln_Pri < 26)  /* don't want to end up off the scale! */
  820.                                                             {
  821.                                                             if (wide = 1 - wide)
  822.                                                                 GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
  823.                                                                                     GTSL_Min,   -128,
  824.                                                                                     GTSL_Max,   127,
  825.                                                                                     TAG_END);
  826.                                                             else
  827.                                                                 GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
  828.                                                                                     GTSL_Min,   -25,
  829.                                                                                     GTSL_Max,   25,
  830.                                                                                     TAG_END);
  831.                                                             }
  832.                                                         }
  833.                                                     break;
  834.  
  835.                                                 case 95:  /* Help key */
  836.                                                     busyPointer(myWindow, &tinyReq, FALSE);
  837.                                                     EasyRequest(NULL, &about, NULL, NULL);
  838.                                                     normalPointer(myWindow, &tinyReq, FALSE);
  839.                                                     break;
  840.                                                 }
  841.                                             break;
  842.                                         }
  843.                                     }
  844.                                 }
  845.                             while (!exit);
  846.                             }
  847.  
  848.                         else
  849.                             Enable();
  850.                         }
  851.                     while (update);
  852.  
  853.                     winLeft = myWindow -> LeftEdge;
  854.                     winTop = myWindow -> TopEdge;
  855.                     winWidth = myWindow -> Width;
  856.                     winHeight = myWindow -> Height;
  857.                     if (preserve)
  858.                         {
  859.                         windowValid = TRUE;
  860.                         blank.Width = winWidth - INTERWIDTH * 3 / 2;  /* don't blank borders */
  861.                         blank.Height = winHeight - windowTop - INTERHEIGHT * 2 - 2;
  862.  
  863.                         RemoveGList(myWindow, mainGads, -1);  /* we'll leave the actual window open */
  864.                         EraseImage(myWindow -> RPort, &blank, INTERWIDTH, windowTop);
  865.                         RefreshWindowFrame(myWindow);  /* because it's probably a mess by now... */
  866.                         }
  867.                     else
  868.                         CloseWindow(myWindow);
  869.  
  870.                     FreeRemember(&memoryKey, TRUE);
  871.                     }
  872.                 }
  873.             FreeGadgets(mainGads);
  874.             FreeGadgets(setGads);
  875.             CloseFont(monoFont);
  876.             CloseFont(propFont);
  877.             }
  878.         FreeVisualInfo(visInfo);
  879.         }
  880.     UnlockPubScreen(NULL, myScreen);
  881.     }
  882. return redraw;
  883. }
  884.  
  885.  
  886. int handleSettings(struct Screen *myScreen, struct Window *mainWindow,
  887.                     struct Gadget *setGads, struct Gadget *propFontGad, struct Gadget *monoFontGad, struct Gadget *checkGad,
  888.                     WORD setWidth, WORD setHeight, WORD windowTop)
  889. {
  890. struct Window       *setWindow;
  891. struct IntuiMessage *message;
  892. struct Gadget       *selectedGad;
  893. struct Requester    tinyReq;
  894. WORD                tempConfirm, action = 1, newPropFont = 0, newMonoFont = 0;
  895. UWORD               class;
  896. char                propString[DefFontLength + 1], monoString[DefFontLength + 1],
  897.                     tempPropName[MaxFontLength], tempMonoName[MaxFontLength];
  898. struct DiskObject   *myIcon;
  899. char                **oldTools, **currentTool, *newTools[20], empty[9][MaxFontLength + 10], *string;
  900. int                 tempPropSize, tempMonoSize, oldPos, newPos;
  901.  
  902. if (setWindow = OpenWindowTags(NULL,    WA_Title,       "PriMan Settings",
  903.                                         WA_Gadgets,     setGads,
  904.                                         WA_Left,        mainWindow -> LeftEdge,
  905.                                         WA_Top,         mainWindow -> TopEdge + windowTop - INTERHEIGHT,
  906.                                         WA_Width,       setWidth,
  907.                                         WA_Height,      setHeight,
  908.                                         WA_DragBar,     TRUE,
  909.                                         WA_DepthGadget, TRUE,
  910.                                         WA_Activate,    TRUE,
  911.                                         WA_CloseGadget, TRUE,
  912.                                         WA_RMBTrap,     TRUE,
  913.                                         WA_IDCMP,       WINDOWIDCMP,
  914.                                         WA_PubScreen,   myScreen,
  915.                                         TAG_END))
  916.     {
  917.     GT_RefreshWindow(setWindow, NULL);
  918.     action      = 0;
  919.  
  920.     tempConfirm = confirm;  /* so we can restore it if the user clicks "Cancel" */
  921.     createString(FALSE, &propName, propString, DefFontLength);  /* initial setting for the text box */
  922.     createString(FALSE, &monoName, monoString, DefFontLength);
  923.     strcpy(tempPropName, propName.ta_Name);  /* initial setting for the font requester */
  924.     strcpy(tempMonoName, monoName.ta_Name);
  925.     tempPropSize = propName.ta_YSize;
  926.     tempMonoSize = monoName.ta_YSize;
  927.     GT_SetGadgetAttrs(propFontGad, setWindow, NULL,
  928.                         GTTX_Text, propString,
  929.                         TAG_END);
  930.     GT_SetGadgetAttrs(monoFontGad, setWindow, NULL,
  931.                         GTTX_Text, monoString,
  932.                         TAG_END);
  933.     GT_SetGadgetAttrs(checkGad, setWindow, NULL,
  934.                         GTCB_Checked, confirm,
  935.                         TAG_END);
  936.  
  937.     do
  938.         {
  939.         WaitPort(setWindow -> UserPort);
  940.         message = GT_GetIMsg(setWindow -> UserPort);
  941.         class = message -> Class;
  942.         selectedGad = message -> IAddress;
  943.         GT_ReplyIMsg(message);
  944.  
  945.         switch (class)
  946.             {
  947.             case IDCMP_CLOSEWINDOW:
  948.                 SetPointer(setWindow, waitPointer, 16, 16, -6, 0);  /* helps prevent "flashing" */
  949.                 action = 1;
  950.                 break;
  951.  
  952.             case IDCMP_REFRESHWINDOW:
  953.                 GT_BeginRefresh(setWindow);
  954.                 GT_EndRefresh(setWindow, TRUE);
  955.                 break;
  956.  
  957.             case GADGETUP:
  958.                 switch (selectedGad -> GadgetID)
  959.                     {
  960.                     case CHECKGAD:
  961.                         tempConfirm = (selectedGad -> Flags) & GFLG_SELECTED;
  962.                         break;
  963.  
  964.                     case GFONTGAD:
  965.                         busyPointer(setWindow, &tinyReq, FALSE);
  966.                         if (newPropFont = AslRequestTags(propFontReq,   ASL_Hail,       "Select Gadget Font",
  967.                                                                         ASL_FuncFlags,  NULL,
  968.                                                                         ASL_LeftEdge,   setWindow -> LeftEdge,
  969.                                                                         ASL_TopEdge,    setWindow -> TopEdge + windowTop - INTERHEIGHT,
  970.                                                                         ASL_FontName,   tempPropName,
  971.                                                                         ASL_FontHeight, tempPropSize,
  972.                                                                         TAG_END))
  973.                             {
  974.                             createString(FALSE, &(propFontReq -> fo_Attr), propString, DefFontLength);
  975.                             GT_SetGadgetAttrs(propFontGad, setWindow, NULL,
  976.                                                 GTTX_Text, propString,
  977.                                                 TAG_END);
  978.                             strcpy(tempPropName, propFontReq -> fo_Attr.ta_Name);
  979.                             tempPropSize = propFontReq -> fo_Attr.ta_YSize;
  980.                             }
  981.                         normalPointer(setWindow, &tinyReq, FALSE);
  982.                         break;
  983.  
  984.                     case LFONTGAD:
  985.                         busyPointer(setWindow, &tinyReq, FALSE);
  986.                         if (newMonoFont = AslRequestTags(monoFontReq,   ASL_Hail,       "Select Task List Font",
  987.                                                                         ASL_FuncFlags,  FONF_FIXEDWIDTH,
  988.                                                                         ASL_LeftEdge,   setWindow -> LeftEdge,
  989.                                                                         ASL_TopEdge,    setWindow -> TopEdge + windowTop - INTERHEIGHT,
  990.                                                                         ASL_FontName,   tempMonoName,
  991.                                                                         ASL_FontHeight, tempMonoSize,
  992.                                                                         TAG_END))
  993.                             {
  994.                             createString(FALSE, &(monoFontReq -> fo_Attr), monoString, DefFontLength);
  995.                             GT_SetGadgetAttrs(monoFontGad, setWindow, NULL,
  996.                                                 GTTX_Text, monoString,
  997.                                                 TAG_END);
  998.                             strcpy(tempMonoName, monoFontReq -> fo_Attr.ta_Name);
  999.                             tempMonoSize = monoFontReq -> fo_Attr.ta_YSize;
  1000.                             }
  1001.                         normalPointer(setWindow, &tinyReq, FALSE);
  1002.                         break;
  1003.  
  1004.                     case SAVEGAD:
  1005.                     case USEGAD:
  1006.                         busyPointer(setWindow, &tinyReq, TRUE);
  1007.                         action = 1;
  1008.                         confirm = tempConfirm;
  1009.  
  1010.                         if (newPropFont && (strcmp((propFontReq -> fo_Attr).ta_Name, propName.ta_Name)
  1011.                                             || !((propFontReq -> fo_Attr).ta_YSize == propName.ta_YSize)))
  1012.                             {
  1013.                             strcpy(propName.ta_Name, (propFontReq -> fo_Attr).ta_Name);
  1014.                             propName.ta_YSize = (propFontReq -> fo_Attr).ta_YSize;
  1015.                             action = 2;
  1016.                             }
  1017.  
  1018.                         if (newMonoFont && (strcmp((monoFontReq -> fo_Attr).ta_Name, monoName.ta_Name)
  1019.                                             || !((monoFontReq -> fo_Attr).ta_YSize == monoName.ta_YSize)))
  1020.                             {
  1021.                             strcpy(monoName.ta_Name, (monoFontReq -> fo_Attr).ta_Name);
  1022.                             monoName.ta_YSize = (monoFontReq -> fo_Attr).ta_YSize;
  1023.                             action = 2;
  1024.                             }
  1025.  
  1026.                         if (selectedGad -> GadgetID == SAVEGAD)
  1027.                             {
  1028.                             if (myIcon = GetDiskObject(myName));
  1029.                                 {
  1030.                                 currentTool = oldTools = myIcon -> do_ToolTypes;  /* existing ToolTypes */
  1031.  
  1032.                                 oldPos = newPos = 0;
  1033.                                 while (string = currentTool[oldPos++])
  1034.                                     if (strncmp(string, "LEFT", 4) && strncmp(string, "TOP", 3)
  1035.                                         && strncmp(string, "WIDTH", 5) && strncmp(string, "HEIGHT", 6)
  1036.                                         && strncmp(string, "GADFONT", 7) && strncmp(string, "GADSIZE", 7)
  1037.                                         && strncmp(string, "LISTFONT", 8) && strncmp(string, "LISTSIZE", 8)
  1038.                                         && strncmp(string, "CONFIRM", 7))  /* get rid of our ones */
  1039.                                         newTools[newPos++] = string;
  1040.  
  1041.                                 sprintf(empty[0], "LEFT=%d", mainWindow -> LeftEdge);
  1042.                                 sprintf(empty[1], "TOP=%d", mainWindow -> TopEdge);
  1043.                                 sprintf(empty[2], "WIDTH=%d", mainWindow -> Width);
  1044.                                 sprintf(empty[3], "HEIGHT=%d", mainWindow -> Height);
  1045.                                 sprintf(empty[4], "GADFONT=%s", propName.ta_Name);
  1046.                                 sprintf(empty[5], "GADSIZE=%d", propName.ta_YSize);
  1047.                                 sprintf(empty[6], "LISTFONT=%s", monoName.ta_Name);
  1048.                                 sprintf(empty[7], "LISTSIZE=%d", monoName.ta_YSize);
  1049.                                 sprintf(empty[8], "CONFIRM=%s", confirm ? "YES" : "NO");
  1050.  
  1051.                                 for (oldPos = 0; oldPos < 9;)
  1052.                                     newTools[newPos++] = empty[oldPos++];  /* write out our ones at end */
  1053.  
  1054.                                 newTools[newPos] = NULL;  /* end of list */
  1055.                                 myIcon -> do_ToolTypes = newTools;
  1056.                                 PutDiskObject(myName, myIcon);
  1057.                                 myIcon -> do_ToolTypes = oldTools;  /* restore original pointer before freeing memory */
  1058.                                 FreeDiskObject(myIcon);
  1059.                                 }
  1060.                             }
  1061.                         normalPointer(setWindow, &tinyReq, TRUE);
  1062.                         break;
  1063.  
  1064.                     case CANCELGAD:
  1065.                         SetPointer(setWindow, waitPointer, 16, 16, -6, 0);
  1066.                         action = 1;
  1067.                         break;
  1068.                     }
  1069.                 break;
  1070.             }
  1071.         }
  1072.     while (!action);
  1073.     CloseWindow(setWindow);
  1074.     }
  1075. return action - 1;
  1076. }
  1077.